import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Test01 {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        int n = nums.length;
        //如果数组长度为空或者元素数小于3——不满足题意
        if (nums == null || n < 3) {
            return res;
        }
        //排序
        Arrays.sort(nums);
        //外层for循环遍历第一个指针
        for (int i = 0; i < n; i++) {
            /*这里的0可以理解为“三数之和”
            * 当前数组已经升序排列。
            * 如果第一个数大于三数之和，那么它与其他两数字和也大于目标值
            * 所以跳过*/
            if (nums[i] > 0) {
                return res;
            }
            //如果第一个指针不指向第一个元素
            //且当前元素与其前一个元素相同，跳过此次循环
            if (i > 0 && nums[i] == nums[i - 1]) {
                continue;
            }
            //其他两个指针：一个指向第一指针的下一位，另一个指向数组末尾
            int L = i + 1;
            int R = n - 1;
            while (L < R) {
                //如果三指针满足题意，则将其放入数组中
                if (nums[i] + nums[L] + nums[R] == 0) {
                    List<Integer> triplet = new ArrayList<>();
                    triplet.add(nums[i]);
                    triplet.add(nums[L]);
                    triplet.add(nums[R]);
                    res.add(triplet);
                    /*对左右指针所指元素进行去重
                    * 如果当前值与下一个值相等，指针后移*/
                    while (L < R && nums[L] == nums[L + 1]) {
                        L++;
                    }
                    while (L < R && nums[R] == nums[R - 1]) {
                        R--;
                    }
                    L++;
                    R--;
                } else if (nums[i] + nums[L] + nums[R] > 0) {
                    R--;
                } else {
                    L++;
                }
            }
        }
        return res;
    }
}
